<?php

/*
 * Created on
 * Date: 2007-12-4
 * Author: William Yang
 */
require_once(dirname(__FILE__)."/../common/constants.php");
require_once(DB_SESSION_DIR_PATH."/db_operator.php");
require_once(DB_SESSION_DIR_PATH."/db_obj_defs.php");

class MatchManager extends Match {
	public function register() {
		$id = parent::register(CONFIGURATION_DIR_PATH."/create_match.xml",
								TRUE);
		return $id;
	}

	/*
	 * All the requests to this match will be returned.
	 * 
	 * Return value: an array containing all the MatchRequest objects.
	 */
	public static function show_match_requests($match_uid) {
		$opera = new DatabaseOperator();
		$opera->config(CONFIGURATION_DIR_PATH."/match_request_table.xml");
		
		$cList = new SqlCondList();
		$cList->add_condition(new SqlCondition("matchid", SqlCondition :: EQUAL, $match_uid));

		$requests = $opera->select($cList);

		$ret = array ();
		if (count($requests)) {
			// Direct match requests exist.
			$request_stub = new MatchRequest();
			foreach ($requests as $m) {
				$ret[] = $request_stub->array2copy($m);
			}
		}

		return $ret;
	}

	public function update_info() {
		$operator = new DatabaseOperator();
		$operator->config(CONFIGURATION_DIR_PATH."/match_table.xml");
		
		$info = $this->toArray();

		$stat = DbError::NO_DB_OPERATION_NEEDED;
		if (count($info)) {
			$condList = new SqlCondList();
			$condList->add_condition(new SqlCondition('uid', SqlCondition :: EQUAL, $this->uid));
			$stat = $operator->update($info, $condList);	
		}
		return $stat;
	}

	public static function delete_match($match_uid) {
		$operator = new DatabaseOperator();
		$operator->config(CONFIGURATION_DIR_PATH."/match_result_table.xml");
		
		// Delete match result if possible.		
		$c1 = new SqlCondition("uid", SqlCondition :: EQUAL, $match_uid);
		$cList = new SqlCondList();
		$cList->add_condition($c1);
		$db_stat = $operator->delete($cList);

		if ($db_stat != DbError :: DB_OK)
			return FALSE;

		// Delete match request including direct request if possible.
		$operator->config(CONFIGURATION_DIR_PATH."/match_request_table.xml");
		$c1 = new SqlCondition("matchid", SqlCondition :: EQUAL, $match_uid);
		$cList = new SqlCondList();
		$cList->add_condition($c1);
		$db_stat = $operator->delete($cList);

		if ($db_stat != DbError :: DB_OK)
			return FALSE;
			
		$operator->config(CONFIGURATION_DIR_PATH."/match_direct_request_table.xml");
		$c1 = new SqlCondition("matchid", SqlCondition :: EQUAL, $match_uid);
		$cList = new SqlCondList();
		$cList->add_condition($c1);
		$db_stat = $operator->delete($cList);

		if ($db_stat != DbError :: DB_OK)
			return FALSE;
		
		// Delete the match itself	
		$operator->config(CONFIGURATION_DIR_PATH."/match_table.xml");
		$c1 = new SqlCondition("uid", SqlCondition :: EQUAL, $match_uid);
		$cList = new SqlCondList();
		$cList->add_condition($c1);
		$db_stat = $operator->delete($cList);
		return ($db_stat == DbError :: DB_OK);
	}

	/*
	 * 1. Set the match's rival team's uid. This match is specified by $match_uid.
	 * 2. Update the match requests' status. The accepted requests' status are set to accepted. The 
	 * others are set to cancelled.
	 * 
	 * Parameter:
	 * $match_uid: the match request's uid.
	 * $rival_team_uid: the rival team's uid which is accepted.
	 * 
	 * Return value:
	 * TRUE if database operations succeed. Otherwise FALSE is returned.
	 */
	public static function accept_match_request($match_uid, $rival_team_uid, $bAccept = TRUE) {
		
		$operator = new DatabaseOperator();
				
		/* 
		 * 1. set the rival.
		 * 2. set the match status MATCH_ACCEPTED identifying that the rival is accepted.
		 */ 
		if ($bAccept) {
			$info["rival"] = $rival_team_uid;
			$info["status"] = MatchStatus::MATCH_ACCEPTED;
		} else {
			$info["rival"] = NULL;
			$info["status"] = MatchStatus::MATCH_RECEIVED;
		}
			
		$operator->config(CONFIGURATION_DIR_PATH."/match_table.xml"); 
		$condList = new SqlCondList();
		$condList->add_condition(new SqlCondition('uid', SqlCondition :: EQUAL, $match_uid));
		$stat = $operator->update($info, $condList);
		if (DbError::is_error($stat))
			return FALSE;
		
		$operator->config(CONFIGURATION_DIR_PATH."/match_request_table.xml");
		$accepted = array ();
		$canceled = array ();
		$accepted["status"] = MatchRequestStat :: REQ_ACCEPTED;
		$canceled["status"] = MatchRequestStat :: REQ_CANCELED;

		$condList = new SqlCondList();
		$condList->add_condition(new SqlCondition('matchid', SqlCondition :: EQUAL, $match_uid));
		$condList->add_relation(SqlCondition::_AND);
		$condList->add_condition(new SqlCondition('teamid', SqlCondition :: EQUAL, $rival_team_uid));
		if ($bAccept)
			$stat = $operator->update($accepted, $condList);
		else
			$stat = $operator->update($canceled, $condList);
		if (DbError::is_error($stat))
			return FALSE;
		
		if ($bAccept) {
			$condList = new SqlCondList();
			$condList->add_condition(new SqlCondition('matchid', SqlCondition::EQUAL, $match_uid));
			$condList->add_relation(SqlCondition::_AND);
			$condList->add_condition(new SqlCondition('teamid', SqlCondition::NOTEQUAL, $rival_team_uid));
			$stat = $operator->update($canceled, $condList);
			if (DbError::is_error($stat)) 
				return FALSE;
		}
		return TRUE;
	}
	
	/*
	 * 1. Set the match's rival team's uid. This match is specified by $match_uid.
	 * 2. Update the match requests' status. The accepted requests' status are set to accepted. The 
	 * others are set to cancelled.
	 * 
	 * Parameter:
	 * $match_uid: the match request's uid.
	 * $rival_team_uid: the rival team's uid which is accepted.
	 * 
	 * Return value:
	 * TRUE if database operations succeed. Otherwise FALSE is returned.
	 */
	public static function accept_direct_match_request($match_uid, $rival_team_uid, $bAccept = TRUE) {
		
		$operator = new DatabaseOperator();
				
		/* 
		 * 1. set the rival.
		 * 2. set the match status MATCH_ACCEPTED identifying that the rival is accepted.
		 */ 
		if ($bAccept) {
			//$info["rival"] = $rival_team_uid;
			$info["status"] = MatchStatus::MATCH_ACCEPTED;
		} else {
			//$info["rival"] = NULL;
			$info["status"] = MatchStatus::MATCH_RECEIVED;
		}
			
		$operator->config(CONFIGURATION_DIR_PATH."/match_table.xml"); 
		$condList = new SqlCondList();
		$condList->add_condition(new SqlCondition('uid', SqlCondition :: EQUAL, $match_uid));
		$stat = $operator->update($info, $condList);
		if (DbError::is_error($stat))
			return FALSE;
		
		$operator->config(CONFIGURATION_DIR_PATH."/match_direct_request_table.xml");
		$accepted = array ();
		$canceled = array ();
		$accepted["status"] = MatchRequestStat :: REQ_ACCEPTED;
		$canceled["status"] = MatchRequestStat :: REQ_CANCELED;

		$condList = new SqlCondList();
		$condList->add_condition(new SqlCondition('matchid', SqlCondition :: EQUAL, $match_uid));
		$condList->add_relation(SqlCondition::_AND);
		$condList->add_condition(new SqlCondition('requesteeid', SqlCondition :: EQUAL, $rival_team_uid));
		if ($bAccept)
			$stat = $operator->update($accepted, $condList);
		else
			$stat = $operator->update($canceled, $condList);
		if (DbError::is_error($stat))
			return FALSE;
		
		return TRUE;
	}
	
	/*
	 * List current matches list.
	 */
	public static function query_match_list($condition) {
		$op = new DatabaseOperator();
		$op->config(CONFIGURATION_DIR_PATH."/match_table.xml");
		$ret_array = $op->select($condition);
		
		$return_val = array();
		$mtch_obj = new Match();
		foreach ($ret_array as $item) {
			$return_val[] = $mtch_obj->array2copy($item);
		}
		
		return $return_val;
	}
	
	public function query_by_uids($uid) {
		/*
		 * Query information by the UID specified by $uid.
		 */
		
		$rows = parent::query_by_uids(CONFIGURATION_DIR_PATH."/match_table.xml", $uid);
		if ($rows === NULL) {
			return NULL;
		} else {
			$ret = array();
			$match_delegate = new Match();
			foreach ($rows as $row) {
				$tmp = $match_delegate->array2copy($row);
				$ret[] = $tmp;
			}
			return $ret;
		}
	}
	
	public static function increase_hot_index($match_uid, $delta = 1) {
		$opera = new DatabaseOperator();
		$opera->config(CONFIGURATION_DIR_PATH."/match_table.xml");
		
		$cList = new SqlCondList();
		$cList->add_condition(new SqlCondition("uid", SqlCondition :: EQUAL, $match_uid));
		$target[] = "hot_index";
		
		$idx_arrays = $opera->select($cList, $target);
		$old_idx = $idx_arrays[0]["hot_index"];
		$hot_index = $old_idx + $delta;

		$cList = new SqlCondList();
		$cList->add_condition(new SqlCondition("uid", SqlCondition::EQUAL, $match_uid));
		$update["hot_index"] = $hot_index;
		
		$stat = $opera->update($update, $cList);
		
		if (DbError::is_error($stat))
			return FALSE;
		else
			return TRUE;
	}
	
	public static function query_history_match_by_home_team_uid($home_team_uid, $row_num_required = NULL) {
		$condList = new SqlCondList();
		if ($home_team_uid != NULL) {
			$condList->add_start_bracket();
			$condList->add_condition(new SqlCondition('owner', SqlCondition::EQUAL, $home_team_uid));
			$condList->add_relation(SqlCondition::_OR);
			$condList->add_condition(new SqlCondition('rival', SqlCondition::EQUAL, $home_team_uid));
			$condList->add_end_bracket();
		}
		
		if ($condList->get_cnt_of_condition() >= 1) {
			$condList->add_relation(SqlCondition::_AND);
			$condList->add_condition(new SqlCondition('status', SqlCondition::EQUAL, MatchStatus::MATCH_COMPLETED));
		} else {
			$condList->add_condition(new SqlCondition('status', SqlCondition::EQUAL, MatchStatus::MATCH_COMPLETED));
		}
		
		$condList->add_constraint(new SqlConstraint(SqlConstraint::ORDERBY, "uid"));
		$condList->add_sort(new SqlSort(SqlSort::DESC));
		$condList->add_limit(new SqlLimit($row_num_required));
	
		return MatchManager::query_match_list($condList);
	}
	
	public static function query_pagi_history_match_by_home_team_uid($home_team_uid, $row_num_required = NULL) {
		$condList = new SqlCondList();
		if ($home_team_uid != NULL) {
			$condList->add_start_bracket();
			$condList->add_condition(new SqlCondition('owner', SqlCondition::EQUAL, $home_team_uid));
			$condList->add_relation(SqlCondition::_OR);
			$condList->add_condition(new SqlCondition('rival', SqlCondition::EQUAL, $home_team_uid));
			$condList->add_end_bracket();
		}
		
		if ($condList->get_cnt_of_condition() >= 1) {
			$condList->add_relation(SqlCondition::_AND);
			$condList->add_condition(new SqlCondition('status', SqlCondition::EQUAL, MatchStatus::MATCH_COMPLETED));
		} else {
			$condList->add_condition(new SqlCondition('status', SqlCondition::EQUAL, MatchStatus::MATCH_COMPLETED));
		}
		
		$condList->add_constraint(new SqlConstraint(SqlConstraint::ORDERBY, "uid"));
		$condList->add_sort(new SqlSort(SqlSort::DESC));
		$condList->add_limit(new SqlLimit($row_num_required));
	
		return MatchManager::query_match_list($condList);
	}
	
	public static function done($match_uid, $playdate) {
		/*
		 * 1. Check whether the report is committed.
		 * 
		 * 2. Set to match status to COMPLETED.
		 */
		$m_objs = MatchResultManager::query_by_match_uids($match_uid);
		if (count($m_objs) != 1)
			return MatchActionStat::MATCH_DONE_NO_REPORT;
		
		$opera = new DatabaseOperator();
		$opera->config(CONFIGURATION_DIR_PATH."/match_table.xml");
		
		$cList = new SqlCondList();
		$cList->add_condition(new SqlCondition("uid", SqlCondition::EQUAL, $match_uid));
		$update["status"] = MatchStatus::MATCH_COMPLETED;
		$update["playdate"] = $playdate;
			
		$stat = $opera->update($update, $cList);
		if (DbError::is_error($stat)) {
			return MatchActionStat::MATCH_DONE_FAILURE;
		} else {
			return MatchActionStat::MATCH_DONE_OK;
		}
	}
	
	/*
	 * Parameter:
	 * $by :        0 - By ID
	 * 		1 - By hot index
	 */
	public static function getTop($top, $by = 1) {
		$opera = new DatabaseOperator();
		$opera->config(CONFIGURATION_DIR_PATH."/match_table.xml");
		
		$cList = new SqlCondList();
		
		$cList->add_condition(new SqlCondition("status", SqlCondition::NOTEQUAL, MatchStatus::MATCH_COMPLETED));
		
		if ($by == 1)
			$cList->add_constraint(new SqlConstraint(SqlConstraint::ORDERBY, "hot_index"));
		else
			$cList->add_constraint(new SqlConstraint(SqlConstraint::ORDERBY, "uid"));
		
		$cList->add_sort(new SqlSort(SqlSort::DESC));
		$cList->add_limit(new SqlLimit(0, $top));
		
		$rows = $opera->select($cList);
		
		$ret = array();
			
		$match_delegate = new Match();
		if ($rows != null && count($rows) > 0) {
			foreach ($rows as $row) {
				$tmp = $match_delegate->array2copy($row);
				$ret[] = $tmp;
			}
		}
		return $ret;
	}
}
?>
